<?php

namespace app\admin\controller;

use think\facade\Db;
use think\facade\View;
use think\facade\Request;
use app\admin\service\Auth;
use app\admin\model\AuthGroup;
use app\admin\model\AuthRule;
use app\admin\model\Administrator as AdministratorModel;
use app\admin\model\AuthGroupAccess;
use app\admin\model\AdministratorLog;
use app\common\service\Util;

/**
 * 管理员管理控制器
 * 负责系统管理员账户、权限角色及操作日志的全面管理
 * 
 * 主要功能包括：
 * - 管理员账户CRUD操作及密码管理
 * - 权限角色定义与权限分配
 * - 操作日志记录与查询
 * - 权限节点管理
 * 
 * 数据存储使用'administrator'表替代原'user'表，优化权限控制流程
 */
class Administrator extends Base
{
    /**
     * 渲染管理员列表页面
     * @return \think\Response
     */
    public function userlist()
    {
        return View::fetch('userList');
    }

    /**
     * 获取管理员列表数据（JSON格式）
     * @return \think\response\Json
     */
    public function userListJson()
    {
        $param = Request::get();
        $where = [];
        if (!empty($param['username'])) {
            $where[] = ['username', 'like', '%' . $param['username'] . '%'];
        }
        if (empty($param['limit'])) {
            $param['limit'] = 10;
        }

        $data = Db::name('administrator')->order('administrator.id desc')->where($where)
            ->where('administrator.id', 'not in', [session('uid'), 1])
            ->join('auth_group', 'auth_group.id = administrator.group_id', 'left')
            ->field('administrator.*,auth_group.title')
            ->paginate($param['limit']);
        $items = $data->items();
        if (count($items)) {
            foreach ($items as &$value) {
                $value['last_login_time'] = $value['last_login_time'] ? date('Y-m-d H:i:s', $value['last_login_time']) : '暂无';
            }
        }
        return $this->genTableJson($data, $items);
    }

    /**
     * 添加新管理员
     * 处理管理员账户创建、密码加密及权限组分配
     * @return \think\Response|void
     */
    public function addUser()
    {
        $request = Request::instance();
        if ($request->isAjax()) {
            $post = $request->post();
            $group_id = $post['group_id'];
            unset($post['group_id']);
            $validate = validate('User');
            $res = $validate->check($post);
            if ($res !== true) {
                $this->errorJump($validate->getError(), 'Administrator/userlist');
            } else {
                unset($post['check_password']);
                $post['password'] = md5($post['password']);
                $post['last_login_ip'] = '0.0.0.0';
                $post['add_time'] = time();
                $post['group_id'] = $group_id;
                $post['add_by'] = session('uid');
                $userId = Db::name('administrator')->insertGetId($post);
                Db::name('auth_group_access')->insert(['uid' => $userId, 'group_id' => $group_id]);
                AdministratorLog::addLog([
                    'uid' => session('uid'),
                    'name' => '添加用户' . $post['username'],
                    'url' => $request->path(),
                    'ip' => $request->ip(),
                ]);
                $this->successJump('success', 'Administrator/userlist');
            }
        } else {
            $auth_group = Db::name('auth_group')
                ->field('id,title')
                ->where('status', 1)
                ->order('id desc')
                ->select();
            return View::fetch('add', ['auth_group' => $auth_group]);
        }
    }

    /**
     * 编辑管理员信息
     * 支持基本信息更新和密码修改，系统管理员不可编辑
     * @param int $id 管理员ID
     * @return \think\Response|void
     */
    public function editUser($id)
    {
        $request = Request::instance();
        if ($request->isPost()) {
            $post = $request->post();
            if ($post['id'] == 1) {
                $this->errorJump('系统管理员无法修改', 'Administrator/userlist');
            }
            $group_id = $post['group_id'];
            unset($post['group_id']);
            $validate = validate('User');
            if (empty($post['password']) && empty($post['check_password'])) {
                $res = $validate->scene('edit')->check($post);
                if ($res !== true) {
                    $this->errorJump($validate->getError(), 'Administrator/userlist');
                } else {
                    unset($post['check_password'], $post['password']);
                    Db::name('user')
                        ->where('id', $post['id'])
                        ->update($post);
                    //授予用户权限
                    Auth::setRule($post['id'], $group_id);
                }
            } else {
                $res = $validate->scene('editPassword')->check($post);
                if ($res !== true) {
                    $this->errorJump($validate->getError(), 'Administrator/userlist');
                } else {
                    unset($post['check_password']);
                    $post['password'] = md5($post['password']);
                    Db::name('user')->where('id', $post['id'])->update($post);
                }
            }
            AdministratorLog::addLog([
                'uid' => session('uid'),
                'name' => '修改用户' . $post['username'],
                'url' => $request->path(),
                'ip' => $request->ip(),
            ]);
            $this->successJump('success', 'Administrator/userlist');
        } else {
            $data = Db::name('administrator')->alias('u')
                ->join('auth_group_access a', 'a.uid=u.id', 'left')
                ->field('u.*,a.group_id')
                ->where('u.id', $id)->find();
            $auth_group = Db::name('auth_group')->field('id,title')->order('id desc')->select();
            View::assign('auth_group', $auth_group);
            View::assign('data', $data);
            return View::fetch('edit');
        }
    }

    /**
     * 删除管理员
     * 超级管理员和当前登录用户不可删除，同步清理权限关联
     * @return void
     */
    public function deleteUser()
    {
        $id = Request::post('id');
        $username = Db::name('user')->where('id', $id)->value('username');
        if ((int)$id !== 1) {
            if ($username !== session('username')) {
                AdministratorLog::addLog([
                    'uid' => session('uid'),
                    'name' => '删除用户' . $username,
                    'url' => Request::path(),
                    'ip' => Request::ip(),
                ]);
                Db::name('user')->where('id', $id)->delete();
                Db::name('auth_group_access')->where('uid', $id)->delete();
                $this->successJump('删除成功', 'Administrator/userlist');
            } else {
                $this->errorJump('无法删除当前登录用户', 'Administrator/userlist');
            }
        } else {
            $this->errorJump('超级管理员无法删除', 'Administrator/userlist');
        }
    }

    /**
     * 渲染权限节点列表页面
     * @return \think\Response
     */
    function ruleList()
    {
        return View::fetch('ruleList');
    }

    /**
     * 获取权限节点列表数据（JSON格式）
     * 格式化节点层级关系并返回
     * @return \think\response\Json
     */
    function ruleListJson()
    {
        $authRule = new AuthRule();
        $data = $authRule
            ->order('id desc')
            ->select();
        $list = Util::array2level($data);
        foreach ($list as &$value) {
            $value['title'] = str_repeat('| ---', $value['level'] - 1) . $value['title'];
            $value['icon'] = '<i class="layui-icon ' . $value['icon'] . '"></i>';
        }
        $list['count'] = count($list);

        return Util::ajaxReturn(0, 'success', $list);
    }

    /**
     * 添加权限节点
     * 验证并创建新的权限节点记录
     * @return \think\Response|void
     */
    function addRule()
    {
        $request = Request::instance();
        if ($request->isPost()) {
            $post = $request->post();
            $validate = validate('AuthRule');
            $res = $validate->check($post);
            if ($res == false) {
                $this->errorJump($validate->getError(), 'Administrator/ruleList');
            }
            $authRule = new AuthRule();
            $authRule->save($post);
            $this->successJump('success', 'Administrator/ruleList');
        }
        $auth = AuthRule::order(['sort' => 'asc'])->select();
        $auth = Util::array2level($auth);
        return View::fetch('addRule', [
            'auth' => $auth
        ]);
    }

    /**
     * 编辑权限节点
     * 更新权限节点信息，下次登录生效
     * @param int|null $id 权限节点ID
     * @return \think\Response|void
     */
    function editRule($id = null)
    {
        $request = Request::instance();
        if ($request->isPost()) {
            $post = $request->post();
            $validate = validate('AuthRule');
            //加载场景
            $validate->scene('edit');
            $res = $validate->check($post);
            if ($res == false) {
                $this->errorJump($validate->getError(), 'Administrator/ruleList');
            }
            AuthRule::get($post['id'])->save($post);
            $this->successJump('修改成功,下次登录生效或者刷新浏览器页面', 'Administrator/ruleList');
        }
        $auth = AuthRule::order(['sort' => 'asc'])->select();
        $auth = Util::array2level($auth);
        $data = AuthRule::where('id', $id)->find();
        return View::fetch('editRule', [
            'auth' => $auth,
            'data' => $data
        ]);
    }

    /**
     * 删除权限
     */
    function delRule($id)
    {
        AuthRule::destroy($id);
        $this->successJump('success', 'Administrator/ruleList');
    }

    /**
     * 渲染角色列表页面
     * @return \think\Response
     */
    function roleList()
    {
        return View::fetch('roleList');
    }

    /**
     * 获取角色列表数据（JSON格式）
     * @return \think\response\Json
     */
    function roleListJson()
    {
        $param = Request::get();
        $where = [];
        if (!empty($param['username'])) {
            $where['username'] = $param['username'];
        }
        $data = AuthGroup::where($where)
            ->order('id desc')
            ->paginate($param['limit']);
        return $this->genTableJson($data);
    }

    /**
     * 添加角色
     * 创建新角色并记录操作日志
     * @return \think\Response|void
     */
    function addRole()
    {
        if (Request::isPost()) {
            $post = Request::post();
            $validate = validate('AuthGroup');
            $res = $validate->check($post);
            if (!$res) {
                $this->errorJump($validate->getError(), 'Administrator/roleList');
            } else {
                AuthGroup::insert($post);
                AdministratorLog::addLog([
                    'uid' => session('uid'),
                    'name' => '添加角色' . $post['title'],
                    'url' => Request::path(),
                    'ip' => Request::ip(),
                ]);
                $this->successJump('添加成功', 'Administrator/roleList');
            }
        }
        return View::fetch('addRole');
    }

    /**
     * 编辑角色
     * 更新角色信息及权限规则关联
     * @param int $id 角色ID
     * @return \think\Response|void
     */
    function editRole($id)
    {
        if (Request::isPost()) {
            $post = Request::post();
            $validate = validate('AuthGroup');
            $res = $validate->check($post);
            if (!isset($post['rules'])) {
                $this->errorJump('未授予任何权限,拒绝提交', 'Administrator/roleList');
            }
            if (true !== $res) {
                $this->errorJump($res, 'Administrator/roleList');
            } else {
                $post['rules'] = is_array($post['rules']) ? implode(',', $post['rules']) : '';
                AuthGroup::where('id', $post['id'])->update($post);
                AdministratorLog::addLog([
                    'uid' => session('uid'),
                    'name' => '修改角色' . $post['title'],
                    'url' => Request::path(),
                    'ip' => Request::ip(),
                ]);
                $this->successJump('授权成功', 'Administrator/roleList');
            }
        } else {
            $authGroup = new AuthGroup();
            $authGroupData = $authGroup->find($id);
            return View::fetch('editRole', [
                'authGroup' => $authGroupData
            ]);
        }
    }

    /**
     * 获取权限规则数据
     * 返回指定角色已勾选的权限节点列表
     * @return array
     */
    public function getJson()
    {
        $id = Request::post('id');
        $auth_group_data = Db::name('auth_group')->find($id);
        $auth_rules = explode(',', $auth_group_data['rules']);
        $auth_rule_list = Db::name('auth_rule')->field('id,pid,title')->select();

        foreach ($auth_rule_list as $key => $value) {
            in_array($value['id'], $auth_rules) && $auth_rule_list[$key]['checked'] = true;
        }
        return $auth_rule_list;
    }

    /**
     * 修改管理员密码
     * 验证原密码并更新新密码，需重新登录
     * @return \think\Response|void
     */
    public function editPasswd()
    {
        $request = Request::instance();
        if ($request->isPost()) {
            $post = $request->post();
            $validate = validate('user');
            $validate->scene('editPasswd');
            $res = $validate->check($post);
            if (!$res) {
                $this->errorJump($validate->getError(), 'Administrator/editPasswd');
            }
            $post['password'] = md5($post['password']);
            AdministratorModel::where('id', session('uid'))->update($post);
            AdministratorLog::addLog([
                'uid' => session('uid'),
                'name' => '修改密码',
                'url' => Request::path(),
                'ip' => Request::ip(),
            ]);
            $this->successJump('修改成功,请重新登录...', 'admin/login/logout');
        }
        $sid = session('uid');
        $data = AdministratorModel::get($sid);
        return View::fetch('editPasswd', [
            'data' => $data
        ]);
    }

    /**
     * 删除角色
     * 检查角色关联用户，存在关联时禁止删除
     * @param int $id 角色ID
     * @return void
     */
    public function delRole($id)
    {
        $res = AuthGroupAccess::where('group_id', $id)->find();
        if (!empty($res)) {
            $this->errorJump('有用户已经分配该权限,请先删除用户', 'Administrator/roleList');
        }
        AdministratorLog::addLog([
            'uid' => session('uid'),
            'name' => '删除角色' . AuthGroup::get($id)->title,
            'url' => Request::path(),
            'ip' => Request::ip(),
        ]);
        AuthGroup::destroy($id);
        $this->successJump('删除成功', 'Administrator/roleList');
    }
}
